package com.edushare.common.vo;

import java.util.ArrayList;
import java.util.List;

import com.edushare.common.file.IFileProcessStrategy;
import com.edushare.common.vo.auto._FileDirectories;

public class FileDirectories extends _FileDirectories {

	private static final long serialVersionUID = 669659958644748188L;
	
	public static enum DIRECTORY_OWNER_TYPE{
		UNIVERSITY (10),
		DEPARTMENT (20),
		COURSE_INSTANCE (30),
		USER (40),
		ASSIGNMENT (50), 
		COURSES (60), 
		GROUP(70);
		
		private final int intVal;
		
		DIRECTORY_OWNER_TYPE(int intVal){
			this.intVal = intVal;
		}
		
		public int getIntVal(){
			return intVal;
		}
	}
	
	//File R, W access
	/**
	 * 
	 *  in these two lettered words, first letter denotes role a-dmin, t-eacher, s-tudent and second denotes scope u-niversity, d-epartment, c-ourse
	 * 	ac  tu  su
	 *	ad  td  sd
	 *	au  tc  sc
	 *
	 * The Umbrella rule is as follows. If a access is "sd" that means
	 * 	ac  tu  su
	 * ------------+
	 *	ad  td  sd |
	 *	au  tc  sc |
	 *             |
	 * and "td" means
	 * 
	 * 	ac  tu  su
	 *--------+	
	 *	ad  td| sd
	 *	au  tc| sc
	 *        |
	 *        
	 * Uploader always has download access!!
	 * 
	 */
	
	public static final String ROLE_STUDENT					= "s";
	public static final String ROLE_TEACHER					= "t";
	public static final String ROLE_ADMIN					= "a";
	public static final String ROLE_ANY						= "x";
	public static final String ROLE_MYSELF					= "z";
	public static final String ROLE_GROUP_MEMBER			= "m";
	
	public static final String SCOPE_UNIV					= "u";
	public static final String SCOPE_DEPT					= "d";
	public static final String SCOPE_COURSE					= "c";
	public static final String SCOPE_GROUP					= "g";
	public static final String SCOPE_PUBLIC					= "x";
	public static final String SCOPE_MYSELF					= "z";
	
	public static final String PERM_PUBLIC					= ROLE_ANY + SCOPE_PUBLIC; //access to anyone logged-in or not logged in
	public static final String PERM_PRIVATE					= ROLE_MYSELF + SCOPE_MYSELF; //access to the folder creator only
	
	public static final String PERM_UNIV_STUDENTS			= ROLE_STUDENT + SCOPE_UNIV; //access to all university students == same as public to university level
	public static final String PERM_DEPT_STUDENT			= ROLE_STUDENT + SCOPE_DEPT; //access to all students of a department
	public static final String PERM_COURSE_STUDENT			= ROLE_STUDENT + SCOPE_COURSE; //access to all students of a course
	
	public static final String PERM_UNIV_TEACHER			= ROLE_TEACHER + SCOPE_UNIV; //access to all the teachers of university
	public static final String PERM_DEPT_TEACHER			= ROLE_TEACHER + SCOPE_DEPT; //access to all the teachers of university
	public static final String PERM_COURSE_TEACHER			= ROLE_TEACHER + SCOPE_COURSE; //access to all the teachers of university
	
	public static final String PERM_UNIV_ADMIN				= ROLE_ADMIN + SCOPE_UNIV; //access to UNIV ADMINS ONLY
	public static final String PERM_DEPT_ADMIN				= ROLE_ADMIN + SCOPE_DEPT; //access to UNIV ADMINS and THIS DEPT's ADMIN ONLY
	public static final String PERM_COURSE_ADMIN			= ROLE_ADMIN + SCOPE_COURSE; //access to THIS COURSE ADMIN, DEPT ADMIN and UNIV ADMIN
	
	public static final String PERM_GROUP_MEMBERS			= ROLE_GROUP_MEMBER + SCOPE_GROUP; //accessed by group members only
	
	private IFileProcessStrategy fileProcessStrategy;

	public void setFileProcessStrategy(IFileProcessStrategy fileProcessStrategy) {
		this.fileProcessStrategy = fileProcessStrategy;
	}

	public IFileProcessStrategy getFileProcessStrategy() {
		return fileProcessStrategy;
	}
	
	
	/** 
	 * Returns all permissions in scope decreasing order
	 * NOTE:: SCOPE MUST BE IN DECREASING ORDER BECAUSE FRONT END WILL SHOW ALL OPTIONS BELOW PARENT DIR SCOPE
	 * 
	 */
	public static List<String> getAllPermissions(int directoryOwnerType){
		DIRECTORY_OWNER_TYPE dirOwnerType = getEnumFromInt(directoryOwnerType);
		List<String> permList = new ArrayList<String>();
		
		switch (dirOwnerType) {
		case UNIVERSITY:
			permList.add(PERM_PUBLIC);
			permList.add(PERM_UNIV_STUDENTS);
			permList.add(PERM_UNIV_TEACHER);
			permList.add(PERM_UNIV_ADMIN);
			break;

		case DEPARTMENT:
			permList.add(PERM_PUBLIC);
			permList.add(PERM_UNIV_STUDENTS);
			permList.add(PERM_DEPT_STUDENT);
//			permList.add(PERM_UNIV_TEACHER);
			permList.add(PERM_DEPT_TEACHER);
			permList.add(PERM_DEPT_ADMIN);
			break;
			
		case COURSE_INSTANCE:
			permList.add(PERM_PUBLIC);
			permList.add(PERM_UNIV_STUDENTS);
			permList.add(PERM_DEPT_STUDENT);
			permList.add(PERM_COURSE_STUDENT);
//			permList.add(PERM_UNIV_TEACHER);
//			permList.add(PERM_DEPT_TEACHER);
			permList.add(PERM_COURSE_TEACHER);
			break;
			
		case USER:
			permList.add(PERM_PUBLIC);
			permList.add(PERM_UNIV_STUDENTS);
//			permList.add(PERM_DEPT_STUDENT);
			permList.add(PERM_COURSE_STUDENT);
			permList.add(PERM_PRIVATE);
			
		case GROUP:
			permList.add(PERM_PUBLIC);
			permList.add(PERM_UNIV_STUDENTS);
			permList.add(PERM_GROUP_MEMBERS);
			
		default:
			break;
		}
		
		return permList;
	}
	
	/**
	 * 
	 * @param dirOwnerType
	 * @return Enum for appropriate owner type
	 */
	public static DIRECTORY_OWNER_TYPE getEnumFromInt(int dirOwnerType){
		if(dirOwnerType==DIRECTORY_OWNER_TYPE.UNIVERSITY.getIntVal()){
			return DIRECTORY_OWNER_TYPE.UNIVERSITY;
		}
		else if(dirOwnerType==DIRECTORY_OWNER_TYPE.DEPARTMENT.getIntVal()){
			return DIRECTORY_OWNER_TYPE.DEPARTMENT;
		}
		else if(dirOwnerType==DIRECTORY_OWNER_TYPE.COURSE_INSTANCE.getIntVal()){
			return DIRECTORY_OWNER_TYPE.COURSE_INSTANCE;
		}
		else if(dirOwnerType==DIRECTORY_OWNER_TYPE.COURSES.getIntVal()){
			return DIRECTORY_OWNER_TYPE.COURSES;
		}
		else if(dirOwnerType==DIRECTORY_OWNER_TYPE.GROUP.getIntVal()){
			return DIRECTORY_OWNER_TYPE.GROUP;
		}
		else if(dirOwnerType==DIRECTORY_OWNER_TYPE.ASSIGNMENT.getIntVal()){
			return DIRECTORY_OWNER_TYPE.ASSIGNMENT;
		}else if(dirOwnerType==DIRECTORY_OWNER_TYPE.USER.getIntVal()){
			return DIRECTORY_OWNER_TYPE.USER;
		}else{
			return null;
		}
	}

	public static List<String> getValidFilePermissions(FileDirectories parentDir) {
		List<String> allPermissions = FileDirectories.getAllPermissions(parentDir.getOwnerType());
		List<String> availablePermissions = new ArrayList<String>();
		
		if(parentDir.getDirType().getDirType().equals(FileDirTypes.ROOT_DIR))//Below root all permissions are OK
			availablePermissions = allPermissions;
		else // in all other cases permissions below the parent directory is acceptable
		{
			String readPerm = parentDir.getReadPerm();
			for(int i=0; i< allPermissions.size(); i++){
				String perm = allPermissions.get(i);
				if(perm.equals(readPerm)){
					//All the perms below this should be valid permissions
					for(int j=i; j<allPermissions.size(); j++)
						availablePermissions.add(allPermissions.get(j));
					break;
				}
			}
		}
		return availablePermissions;
	}
	
	
}
